/*
9.27
1.function matrix_calc_taskA,matrix_calc_taskB
2."N" means iteration times
10.2
1.merge the for loop in taskB
2.move memory access variable out of "for loop".
*/
#ifndef _CALC_H_
#define _CALC_H_
//#include<iostream>
//using namespace std;
#ifdef __cplusplus
extern "C"{	
#endif

typedef struct {
	int* 			rowArray;
	const int* 		rowOffset;
	int 			rowArraySize;
	const int* 		columnIndice;
	const double* 	S;
	const double*	valueNormalMatrix;
	double* 		Id;
}TaskMatrixInfoA;

typedef struct {
	const double * 	valueSpiceMatrix;//N*2
	const int* 		rowOffset; 		//n+1
	const int* 		columnIndice; 	//N

	double* 		A;	//N
	double*		 	S;	//nx1
	double*			R;	//nx1
	double* 		H;	//nx1
	const double* 	D;	//N*2
	double* 		IC;	//nx1
	double* 		IG;	//nx1
	double 		alpha;
	int * 			rowArray; //kx1
	int 			rowArraySize;
	void* 			hdl;  //? what's this?
}TaskMatrixInfoB;

void matrix_calc_taskA(TaskMatrixInfoA** listDataList,int N)
{
//	cout<<endl<<"task A:"<<N<<endl;
	for (int i = 0 ;i < N; ++i)
	{	
		int row_array_size= listDataList[i]->rowArraySize;	
		TaskMatrixInfoA * list_Data_List=listDataList[i];
		const double *valueNormalMatrix = list_Data_List->valueNormalMatrix;
		const double *S = list_Data_List->S;
		const int *columnIndice = list_Data_List->columnIndice;
		for (unsigned int it = 0; it < row_array_size; ++it	)
		{
			const int node = list_Data_List->rowArray[it];
			int colum_num = list_Data_List->rowOffset[node + 1];
			double &id=list_Data_List->Id[node];
	//		double tmp=0;
			for (int j = list_Data_List->rowOffset[node];j < colum_num;++j)
			{
				id += valueNormalMatrix[j]*S[columnIndice[j]];
			}
	//		list_Data_List->Id[node]+=tmp;
		}
	}
}

//Task B interface
void matrix_calc_taskB(TaskMatrixInfoB** listDataList,int N)
{
//	cout<<endl<<"taskB: "<<N<<endl;
	for (int i = 0;i<N;i++){
		TaskMatrixInfoB * list_Data_List = listDataList[i];
		int row_array_size = list_Data_List->rowArraySize;
		const double alpha = list_Data_List->alpha;
		double* A = list_Data_List->A;
		const double* S = list_Data_List->S;
		const int* columnIndice=list_Data_List->columnIndice;
		const double* valueSpiceMatrix=list_Data_List->valueSpiceMatrix;

//		cout<<"row_array_size B: "<<row_array_size<<endl;
//		cout<<row_array_size<<" ";
		for(int it = 0;it < row_array_size;++it)
		{
			int row = list_Data_List->rowArray[it];
			const int k1 = row << 1;
			int colum_num = list_Data_List->rowOffset[row + 1];
										
//			double ig_tmp=0;
//			double ic_tmp=0;
			double &ig_tmp = list_Data_List->IG[row];	
			double &ic_tmp = list_Data_List->IC[row];		
		//	cout<<colum_num-list_Data_List->rowOffset[row]<<" ";
			for (int p = list_Data_List->rowOffset[row];p < colum_num;++p){
				const int k = p << 1;
				double cond =valueSpiceMatrix[k];
				double cap  =valueSpiceMatrix[k+1];					
				ig_tmp += cond * S[columnIndice[p]];
				ic_tmp += cap * S[columnIndice[p]];
				//(9)
				A[p] = cond +  cap * alpha;
			}
 			//(7)(8)
 			list_Data_List->IG[row] +=ig_tmp; 
 			list_Data_List->IC[row] +=ic_tmp; 
			list_Data_List->R[row] = list_Data_List->D[k1]-ig_tmp;
			list_Data_List->H[row] = list_Data_List->D[k1+1]-ic_tmp;
		} 
//		cout<<endl;
	}
}

#ifdef __cplusplus
}
#endif

#endif
